Add support for global GPSBabel ini-file.
authoroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 5 Apr 2006 18:00:22 +0000 (18:00 +0000)
committeroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 5 Apr 2006 18:00:22 +0000 (18:00 +0000)
gpsbabel/filter_vecs.c
gpsbabel/inifile.c
gpsbabel/main.c

index b724da9e4122dd317e9070e28301b1ae6455d41c..6924d908530917697b0fea59902b83fb80baaf31 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "defs.h"
 #include "filterdefs.h"
+#include "inifile.h"
 
 typedef struct {
        filter_vecs_t *vec;
@@ -132,41 +133,39 @@ find_filter_vec(char *const vecname, char **opts)
                        continue;
                }
 
+               /* step 1: initialize by inifile or default values */
+               if (vec->vec->args) {
+                       for (ap = vec->vec->args; ap->argstring; ap++) {
+                               char *temp;
+                               
+                               temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring);
+                               if (temp == NULL) temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring);
+                               if (temp == NULL) temp = ap->defaultvalue;
+                               assign_option(vec->name, ap, temp);
+                       }
+               }
+               
+               /* step 2: override settings with command-line values */
                res = strchr(vecname, ',');
                if (res) {
                        *opts = res+1;
 
                        if (vec->vec->args) {
                                for (ap = vec->vec->args; ap->argstring; ap++){
-                                       char *opt = get_option(*opts, 
-                                                       ap->argstring);
-                                       if ( opts ) {
-                                               *ap->argval = opt;
-                                       }
-                                       else if ( ap->defaultvalue ) {
-                                               *ap->argval = xstrdup(
-                                                       ap->defaultvalue);
-                                       }
-                                       else {
-                                               *ap->argval = NULL;
-                                       }
-                               }
-                       }
-               } else {
-                       *opts = NULL;
-                       if (vec->vec->args) {
-                               for (ap = vec->vec->args; ap->argstring; ap++){
-                                       if ( ap->defaultvalue ) {
-                                               *ap->argval = xstrdup(
-                                                       ap->defaultvalue);
-                                       }
-                                       else {
-                                               *ap->argval = NULL;
+                                       char *opt;
+                                       
+                                       opt = get_option(*opts, ap->argstring);
+                                       if ( opt ) {
+                                               assign_option(vec->name, ap, opt);
+                                               xfree(opt);
                                        }
                                }
                        }
                }
 
+               if (global_opts.debug_level >= 1)
+                       disp_vec_options(vec->name, vec->vec->args);
+                       
                xfree(v);
                return vec->vec;
                
@@ -182,7 +181,10 @@ free_filter_vec( filter_vecs_t *fvec )
        
        if ( fvec->args ) {
                for ( ap = fvec->args; ap->argstring; ap++) {
-                       if (ap->argval && *ap->argval) xfree(*ap->argval);
+                       if (ap->argval && *ap->argval) {
+                               xfree(*ap->argval);
+                               *ap->argval = NULL;
+                       }
                }
        }
 }
index 4eb0aa77ec93d41a806a22f1b8a3107d27ae7c5c..5bf47a1c728717eb4bd2f71a3f611a47b70c5cbf 100644 (file)
@@ -48,6 +48,75 @@ typedef struct inifile_section_s
 #define START_BUFSIZE 257
 #define DELTA_BUFSIZE 128
 
+#define GPSBABEL_INIFILE "gpsbabel.ini"
+
+static FILE *
+try_open_gpsbabel_inifile(const char *path)            /* can be empty or NULL */
+{
+       FILE *result;
+       char *buff;
+       int len;
+
+       if (path == NULL) return NULL;
+               
+       len = strlen(path);
+       buff = xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1);
+       strcpy(buff, path);
+       if (len > 0) {
+               char test = buff[len - 1];
+#ifdef __WIN32__
+               if ((test != '\\') && (test != ':'))
+                       strcat(buff, "\\");
+#else
+               if (test != '/')
+                       strcat(buff, "/");
+#endif
+       }
+       strcat(buff, GPSBABEL_INIFILE);
+       result = fopen(buff, "r");
+       xfree(buff);
+       
+       return result;
+}
+
+static FILE *
+open_gpsbabel_inifile(void)
+{
+       FILE *res;
+       char *envstr;
+       
+       envstr = getenv("GPSBABELINI");
+       if (envstr != NULL) {
+               res = fopen(envstr, "r");
+               if (res == NULL) {
+                       warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n");
+                       return NULL;
+               }
+               return res;
+       }
+       res = try_open_gpsbabel_inifile("");    /* PWD */
+       if (res == NULL) {
+#ifdef __WIN32__
+               res = try_open_gpsbabel_inifile(getenv("APPDATA"));
+               if (res == NULL) res = try_open_gpsbabel_inifile(getenv("WINDIR"));
+               if (res == NULL) res = try_open_gpsbabel_inifile(getenv("SYSTEMROOT"));
+#else
+               if ((envstr = getenv("HOME")) != NULL) {
+                       char *path;
+                       
+                       path = xmalloc(strlen(envstr) + 11);
+                       strcpy(path, envstr);
+                       strcat(path, "/.gpsbabel");
+                       res = try_open_gpsbabel_inifile(path);
+                       xfree(path);
+               }
+               if (res == NULL) res = try_open_gpsbabel_inifile("/usr/local/etc");
+               if (res == NULL) res = try_open_gpsbabel_inifile("/etc");
+#endif
+               if (res == NULL) return NULL;
+       }
+}
+
 static void
 inifile_load_file(FILE *fin, inifile_t *inifile, const char *myname)
 {
@@ -70,7 +139,8 @@ inifile_load_file(FILE *fin, inifile_t *inifile, const char *myname)
                }
                
                cin = lrtrim(buf);
-               if (*cin == '\0') continue;
+               if (*cin == '\0') continue;                     /* skip empty lines */
+               if ((*cin == '#') || (*cin == ';')) continue;   /* skip comments */
                
                if (*cin == '[')
                {
@@ -130,6 +200,8 @@ inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *k
 {
        queue *elem, *tmp;
        
+       if (inifile == NULL) return NULL;
+       
        QUEUE_FOR_EACH(&inifile->secs, elem, tmp)
        {
                inifile_section_t *sec = (inifile_section_t *) elem;
@@ -158,14 +230,20 @@ inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *k
        inifile_init:
          reads inifile filename into memory
          myname represents the calling module
+         
+         filename == NULL: try to open global gpsbabel.ini
  */
 inifile_t *
 inifile_init(const char *filename, const char *myname)
 {
        inifile_t *result;
-       FILE *fin;
+       FILE *fin = NULL;
        
-       fin = xfopen(filename, "r", myname);
+       if (filename == NULL) {
+               fin = open_gpsbabel_inifile();
+               if (fin == NULL) return NULL;
+       }
+       else fin = xfopen(filename, "r", myname);
        
        result = xcalloc(1, sizeof(*result));
        QUEUE_INIT(&result->secs);
index 7eb25e18731c9c16e5c81d8f85be3ffc418c418f..c0e42693be7ec47219a784989e2e29ff7549a1d6 100644 (file)
 #include "filterdefs.h"
 #include "cet.h"
 #include "cet_util.h"
+#include "inifile.h"
 #include <ctype.h>
 
+#define MYNAME "main"
+
 static void
 usage(const char *pname, int shorter)
 {
@@ -49,6 +52,7 @@ usage(const char *pname, int shorter)
 "    (without the quotes) are all valid file type specifications.\n"
 "\n"
 "Options:\n"
+"    -p               Prereferences file (gpsbabel.ini)\n"
 "    -s               Synthesize shortnames\n"
 "    -r               Process route information\n"
 "    -t               Process track information\n"
@@ -100,8 +104,9 @@ main(int argc, char *argv[])
 
        global_opts.objective = wptdata;
        global_opts.masked_objective = NOTHINGMASK;     /* this makes the default mask behaviour slightly different */
-       global_opts.charset = NULL;                     /* #ifdef UTF8_SUPPORT */
-       global_opts.charset_name = NULL;                        /* #ifdef UTF8_SUPPORT */
+       global_opts.charset = NULL;
+       global_opts.charset_name = NULL;
+       global_opts.inifile = NULL;
 
        gpsbabel_now = time(NULL);                      /* gpsbabel startup-time */
        gpsbabel_time = current_time();                 /* same like gpsbabel_now, but freezed to zero during testo */
@@ -114,6 +119,9 @@ main(int argc, char *argv[])
        }
        debug_mem_output( "\n" );
 #endif
+       if (gpsbabel_time != 0) {       /* within testo ? */
+               global_opts.inifile = inifile_init(NULL, MYNAME);
+       }
        
        cet_register();
        waypt_init();
@@ -336,6 +344,14 @@ main(int argc, char *argv[])
                        case 'l':
                                cet_disp_character_set_names(stdout);
                                exit(0);
+                       case 'p':
+                               optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn];
+                               inifile_done(global_opts.inifile);
+                               if (strcmp(optarg, "") == 0)    /* from GUI to preserve inconsistent options */
+                                       global_opts.inifile = NULL;
+                               else
+                                       global_opts.inifile = inifile_init(optarg, MYNAME);
+                               break;
 
                }
        }
@@ -401,6 +417,7 @@ main(int argc, char *argv[])
        route_flush_all();
        exit_vecs();
        exit_filter_vecs();
+       inifile_done(global_opts.inifile);
 
 #ifdef DEBUG_MEM
        debug_mem_close();